<?php

namespace App\Http\Controllers\Api\Order;

use DB;

use Carbon\Carbon;

use App\Service\WdhService;

use App\Service\Order\ApiService;

use App\Models\Bill\Bill;  //订单主表

use App\Models\Bill\BillGoods;  //订单商品表

use App\Models\Bill\BillPay;  //订单支付方式表

use App\Models\Bill\BillErp;  //订单状态推送ERP表

use App\Models\Bill\BillProcess;  //订单流程表

use App\Models\Bill\BillTrace;  //订单轨迹表

use App\Models\Bill\BillFinishTemp;  //订单完成临时表

use App\Models\Bill\BillUsePromotion;  //订单促销记录表

use App\Models\Bill\BillUseCardCoupon;  //下单使用卡券记录表

use App\Models\Bill\BillCodePool;  //订单生码表

use App\Models\Bill\BillCoupon;  //订单发放优惠券

use App\Models\Bill\BillFinish;  //已完成的订单表

use App\Models\Bill\BillReturn;  //订单退货表

use App\Models\Bill\BillRefund;  //退款单表

use App\Models\Card\CardCoupon;  //卡券表

use App\Models\Activity\ActivityCodePool;  //活动码池子表

use App\Models\Mall\MallMaster;  //门店主表

use App\Models\ConfigureFunction;  //配置主表

use App\Models\Log\LogDetail;  //公共日志表

use App\Models\Pay\SysPaytype;  //支付方式表

use App\Models\Tg\Tg; //团购维护表

use App\Models\Tg\TgGoods; //团购维护商品表

use App\Models\Goods\GoodsSaleEdit;  //待发布商品表

use App\Models\Promotion\PromotionCustNumLog; //促销会员购买个数记录表

use App\Models\Promotion\PromotionPointsExchange; //积分兑换表

use App\Models\Customer\Customer; //会员主表

use Illuminate\Http\Request;

use App\Http\Controllers\Controller;

use Illuminate\Support\Facades\Redis as Redis;

class OutwardOrderController extends Controller
{

    /**
     * 订单配送接口（订单发货）
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function delivery( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' => '参数order_no不能为空']);
        }

        //根据订单号查询订单信息
        $bill_master = Bill::find( $order_no );

        if ( !$bill_master ) {
            return response()->json(['code' => 100002, 'message' => '订单信息不存在']);
        }

        //订单状态:0、建立 1、确认 2、发货 3、配送 4、完成 5、取消 6、异常
        if ( $bill_master['bill_status'] == 0 ) {
            return response()->json(['code' => 100003, 'message' => '订单未审核,请检查订单状态']);
        }
        if ( in_array( $bill_master['bill_status'],array(2, 3, 4, 7, 8) ) ) {
            return response()->json(['code' => 100004, 'message' => '订单已配送,请检查订单状态']);
        }
        if ( $bill_master['bill_status'] == 5 || $bill_master['bill_status'] == 6 ) {
            return response()->json(['code' => 100005, 'message' => '订单已取消,请检查订单状态']);
        }

        try {

            //开启事务
            DB::beginTransaction();

                //查询订单生码规则
                $bill_create_pickup_code = ConfigureFunction::getConfigureField(21, 'bill_create_pickup_code');

                $deliver_express = '';
                if ( $bill_master['ziti'] == 0 || $bill_create_pickup_code == 0 ) { //配送方式为‘送货上门’ 或者 “订单不生码” 改变订单状态为发货

                    $bill_master['bill_status'] = 2;

                    //查询订单完成临时表
                    $bill_finish_obj = BillFinishTemp::find( $order_no );

                    if ( !$bill_finish_obj ) {

                        $bill_finish = new BillFinishTemp;
                        $bill_finish->uuid = makeUuid();
                        $bill_finish->timeStamp = Carbon::now();
                        $bill_finish->creator = 'api';
                        $bill_finish->createTime = Carbon::now();
                        $bill_finish->bill_finish_date = Carbon::now();
                        $bill_finish->bill_no = $order_no;
                        $bill_finish->save();
                    }

                    $args_data['express_no'] = ''; //快递单号
                    $args_data['express_company'] = ''; //快递公司

                    if ( !empty( $args_data['express_no'] ) && !empty( $args_data['express_company'] ) ) { //如果存在快递单号和快递公司

                        $process_data['express'] = [
                            'number' => $args_data['express_no'],
                            'name' => $args_data['express_company']
                        ];

                        $deliver_express = '；' . $args_data['express_company'] . '快递：'. $args_data['express_no'];

                        $order_obj = new Bill;
                        $order_obj->uuid = makeUuid();
                        $order_obj->timeStamp = Carbon::now();
                        $order_obj->creator = 'api';
                        $order_obj->bill_status = 2; //订单状态:发货
                        $order_obj->express_number = $args_data['express_no'];
                        $order_obj->express_company = $args_data['express_company'];
                        $order_obj->save();
                    }

                    //保存日志
                    $args_array = [
                        'logCategoryID' => 1,
                        'logItem' => $order_no,
                        'extend_1' => '订单发货',
                        'extend_5' => 2
                    ];
                    self::orderLog( $args_array );
                }

                if ( $bill_master['ziti'] == 1) { //门店自提 1.是 0.否

                    $process_data['message'] = [
                        'template_scene_id' => 10017
                    ];

                    //生成订单轨迹
                    self::trace( $order_no, 2, '您购买的商品已发货，我们将尽快配送至指定门店，请耐心等待');

                } else {

                    $process_data['message'] = [
                        'template_scene_id' => 10018
                    ];

                    //生成订单轨迹
                    self::trace( $order_no, 2, '您的订单已发货' . $deliver_express);
                }

                //保存订单流程信息
                $bill_process = new BillProcess;
                $bill_process->uuid = makeUuid();
                $bill_process->timeStamp = Carbon::now();
                $bill_process->creator = 'api';
                $bill_process->createTime = Carbon::now();
                $bill_process->bill_no = $order_no;
                $bill_process->bill_status = $bill_master['bill_status'];
                $bill_process->process_json = json_encode( $process_data );
                $bill_process->save();

                //异步推送订单消息
                $args_data = [
                    'uid' => $bill_process->uuid
                ];

                ApiService::billProcess( $args_data );

                //异步推送传入ERP处理
                self::pushBillToErp( ['bill_status' => 2, 'bill_no' => $order_no ] );

                DB::commit();

            } catch (\Exception $e) {

                DB::rollBack();

                return response()->json(['code' => 100006, 'message' => '订单配送失败']);
            }

        return response()->json(['code' => 200, 'message' => 'ok']);
    }


    /**
     * 订单完成接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function finish( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' => '参数order_no不能为空']);
        }

        //调用订单完成公共方法
        $result_array = self::commonFinish( $order_no );

        return $result_array;

    }


    /**
     * 订单快速完成接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function fastFinish( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' => '参数order_no不能为空']);
        }

        try {

            //开启事务
            DB::beginTransaction();

            //根据订单号查询订单信息
            $bill_master = Bill::find( $order_no );

            if ( $bill_master ) {

                if ( $bill_master['pay_type'] == 1 ) { //货到付款的订单，更新支付状态为人工已审

                    $bill_pay = BillPay::where(['bill_no'=>$order_no,'paid_confirm_status'=> 0 ])
                        ->update(['pay_time'=>Carbon::now(),'paid_confirm_status'=>2,'deduct_amount'=>'pay_amount']);
                    if ( $bill_pay <= 0 ) {
                        return response()->json(['code' => 100002, 'message' => '订单支付状态更新失败']);
                    }
                }

                //调用订单完成公共方法
                $result_array = self::commonFinish( $order_no );

                if ( $result_array['code'] != 200 ) {
                    return response()->json(['code' => $result_array['code'], 'message' => $result_array['message']]);
                }
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100003, 'message' => '订单快速完成失败']);
        }

        return response()->json(['code' => 200, 'message' => 'ok']);
    }


    /**
     * 订单快速完成（无需经过发货流程）
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function fastBarcodeFinish( Request $request )
    {

        $barcode = $request->input('barcode'); //订单提货码

        //订单提货码
        if ( empty( $barcode ) ) {
            return response()->json(['code' => 100001, 'message' => '参数barcode不能为空']);
        }

        //查询活动码信息
        $code_pool_obj = ActivityCodePool::select('bill_no','code_type')->find( $barcode );
        if ( !$code_pool_obj ) {
            return response()->json(['code' => 100002, 'message' => '订单提货码信息未找到']);
        }

        //券码类型
        if ( $code_pool_obj['code_type'] != 1 ) {
            return response()->json(['code' => 100003, 'message' => '券码类型有误']);
        }

        //订单号
        if ( empty( $code_pool_obj['bill_no'] ) ) {
            return response()->json(['code' => 100004, 'message' => '未找到订单提货券对应的订单号']);
        }

        try {

            //开启事务
            DB::beginTransaction();

            //更新订单状态 bill_status订单状态:0、建立 1、确认 2、发货 3、配送 4、完成 5、取消 6、异常 7、配货中 8、配货完成
            $bill_master = Bill::where(['bill_no'=>$code_pool_obj['bill_no'],'bill_status'=>1])->update(['bill_status'=>3]);
            if ( $bill_master <= 0 ) {
                return response()->json(['code' => 100005, 'message' => '订单状态更新失败']);
            }

            //调用订单完成公共方法
            $result_array = self::commonFinish( $code_pool_obj['bill_no'] );

            if ( $result_array['code'] != 200 ) {
                return response()->json(['code' => $result_array['code'], 'message' =>$result_array['message']]);
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100006, 'message' => '订单快速完成失败']);
        }

        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 订单取消接口(待完成)
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function cancel( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号
        $cancel_reason = $request->input('cancel_reason'); //取消原因

        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数order_no不能为空']);
        }
        if ( empty( $args_data['cancel_reason'] ) ) {
            return response()->json(['code' => 100002, 'message' =>'参数cancel_reason不能为空']);
        }

        $order = Bill::find( $order_no );
        if ( !$order ) {
            return response()->json(['code' => 100003, 'message' =>'订单信息不存在']);
        }
        if ( $order['split_type'] == 2 ) {
            return response()->json(['code' => 100004, 'message' =>'订单已拆分,不可取消']);
        }
        if ( $order['bill_status'] == 2 ) {
            return response()->json(['code' => 100005, 'message' =>'订单已发货,不可取消']);
        }
        if ( $order['bill_status'] == 3 ) {
            return response()->json(['code' => 100006, 'message' =>'订单已配送,不可取消']);
        }
        if ( $order['bill_status'] == 4 ) {
            return response()->json(['code' => 100007, 'message' =>'订单已完成,不可取消']);
        }
        if ( $order['bill_status'] == 5 ) {
            return response()->json(['code' => 100008, 'message' =>'订单已取消,不可取消']);
        }
        if ( $order['bill_status'] == 6 ) {
            return response()->json(['code' => 100009, 'message' =>'订单已拒收,不可取消']);
        }

        try {

            //开启事务
            DB::beginTransaction();

            //查询订单商品表
            $bill_goods = BillGoods::getGoods( $order_no );
            if ( !$bill_goods ) {
                return response()->json(['code' => 100010, 'message' =>'订单商品信息不存在']);
            }

            $bill_code_sql = 'ActivityCodePool';
            //检查是否存在放弃或者核销的码子
            $bill_code_result = $bill_code_sql::where( ['bill_no'=>$order_no ] )->get()->toArray();
            if ( !$bill_code_result ) {
                $bill_code_sql = 'ActivityCodePoolHistory';
                $bill_code_result = $bill_code_sql::where( ['bill_no'=>$order_no ] )->get()->toArray();
            }
            if ( !empty( $bill_code_result ) ) {
                foreach ( $bill_code_result as &$code ) {
                    if ( $code['code_status'] == 2 && $code['code_use_type'] == 3 ) {
                        return response()->json(['code' => 100011, 'message' =>'订单已存在提货,不可取消']);
                    }
                    if ( $code['code_status'] == 3 ) {
                        return response()->json(['code' => 100012, 'message' =>'订单券码已放弃,不可取消']);
                    }
                }

                //订单券码总数
                $bill_code_num = count($bill_code_result);

                /**
                 * 将订单券码状态更新为“已放弃”
                 * 1、活动订单:2、特价购订单 3、闪购订单  7、众筹单
                 */
                if ( in_array( $order['billType'], array(2,3,7) ) ) {

                    $code_rows = $bill_code_sql::where(['bill_no'=>$order_no,'code_status'=>1 ])->update(['code_status'=>3]);
                    if ( $code_rows != $bill_code_num ) {
                        return response()->json(['code' => 100013, 'message' =>'更新订单状态码失败']);
                    }
                } else {
                    $bill_code_sql::where(['bill_no'=>$order_no])->update(['code_status'=>3]);
                }
            }

            //查询订单积分抵扣金额
            $bill_points_money = 0;
            if ( $order['bill_points_money'] > 0 || $order['bill_pointsPrice'] > 0 ) {

                //查询积分设置
                $points_exchange_ratio = ConfigureFunction::getConfigureField(2, 'points_exchange_ratio');
                $bill_points_money = $order['bill_points_money'] * $points_exchange_ratio + $order['bill_pointsPrice'];
            }

            //查询订单余额抵扣金额
            $bill_balance_money = 0;
            if ( $order['bill_balance_money'] > 0 ) {
                $bill_balance_money = $order['bill_balance_money'];
            }

            //清空促销记录
            BillUsePromotion::where(['pcustID' => $order['pcustID'], 'bill_no' => $order_no])->delete();

            //卡券回滚
            $card_coupon = self::rollbackCoupon( $order_no );
            if ( $card_coupon['code'] != 200 ) {
                return array('code' => $card_coupon['code'], 'message' => $card_coupon['code']);
            }

            //保存日志
            $args_data = [
                'logCategoryID' => 1,
                'logItem' => $order_no,
                'extend_1' => '订单'. $order_no . '取消',
                'extend_5' => $order['bill_status']
            ];
            self::orderLog( $args_data );

            /*
             * 订单取消时生成退款单
             * 退回积分、余额
             * 检查在线支付是否可自动退回。如果可以则自动退回金额
             */
            $args_data = array(
                'return_points' =>$bill_points_money,
                'return_balance' => $bill_balance_money,
                'bill_no' => $order_no,
                'refund_source' => 2
            );
            $result_data = ApiService::storeOrderReturn( $args_data );
            if ( $result_data['code'] != 200 ) {
                return array('code' => $card_coupon['code'], 'message' => $card_coupon['code']);
            }

            //更新订单状态和订单取消原因
            Bill::where(['bill_no'=>$order_no])->update(['bill_status'=>5,'bill_cancel_reason'=>$args_data['cancel_reason']]);

           self::trace( $order_no, 5, '您的订单已取消' .$args_data['cancel_reason']);

            $is_choose_goods_by_mall = ConfigureFunction::getConfigureField(8, 'is_choose_goods_by_mall'); //是否根据门店筛选商品
            $mallID = 1;
            if ( $is_choose_goods_by_mall && $order['mallID'] > 0 ) {
                $mallID = $order['mallID'];
            }

//-------------------//更新库存


            if ( $order['billType'] == 9 ) {

                Tg::where(['tuan_id'=>$order['activity_id']])->decrement('buy_count',$bill_goods[0]['goods_amount']);

                TgGoods::where(['tuan_id'=>$order['activity_id'],'postID'=>$bill_goods[0]['goods_postID']])->decrement('buy_count',$bill_goods[0]['goods_amount']);
            }
            //回滚积分商城库存
            if ( $order['billType'] == 4 ) {
                foreach ( $bill_goods as $item ) {
                    //更新购买记录
                    PromotionCustNumLog::where(['promotion_id'=>$item['goods_groupID'],'postID'=>$item['goods_postID'],'pcustID'=>$item['pcustID']])
                        ->decrement('num',$item['goods_amount']);
                    //更新积分商品库存
                    PromotionPointsExchange::where(['promotion_id'=>$item['goods_groupID']])->decrement('buy_num',$item['goods_amount']);
                }
            }

            //推送订单取消消息模板
            $push_array = array(
                'bill_status' => '1',
                'bill_no' => $order_no
            );
            ApiService::billMessageTemplate( $push_array );

            //异步推送传入ERP处理
            self::pushBillToErp(
                array(
                    'bill_status'=> 5,
                    'bill_no'=> $order_no,
                    'remark'=> $cancel_reason
                )
            );

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return return_exception($e, '订单取消');
        }


        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 获取订单接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function get( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数order_no不能为空']);
        }

        //根据订单号查询订单信息
        $order_data = Bill::find( $order_no );
        if ( !$order_data ) {
            return response()->json(['code' => 100002, 'message' =>'订单信息不存在']);
        }

        //根据门店id查询门店信息
        $mall_master = MallMaster::find( $order_data['mallID'] );
        if ( !$mall_master ) {
            return response()->json(['code' => 100003, 'message' =>'门店信息不存在']);
        }

        //根据订单号查询订单商品信息
        $bill_goods = BillGoods::where( ['bill_no'=>$order_no] )->get()->toArray();
        if ( !$bill_goods ) {
            return response()->json(['code' => 100004, 'message' =>'订单商品信息不存在']);
        }

        //根据订单号查询订单支付信息
        $bill_pay = BillPay::select('payTypeName','pay_time','pay_amount','pay_code','type','payTypeID')
                    ->where( ['bill_no'=>$order_no] )->get()->toArray();
        if ( !$bill_pay ) {
            return response()->json(['code' => 100005, 'message' =>'订单支付信息不存在']);
        }

        //推送数据数组
        $bill_push_data = [
            "order_no" => app_to_string((string)$order_no ),
            "shop_code" => 'WDH',
            "create_time"=> app_to_string( $order_data['createTime'] ),
            "pay_state"=> app_to_int( $order_data['pay_state'] ),
            "pay_time"=> app_to_string( $order_data['payed_time'] ),
            "total"=>app_to_decimal( $order_data['bill_totalMoney'] ),
            "freight"=>app_to_decimal( $order_data['deliver_fee'] ),
            "require_invoice"=> $order_data['invoice']  == 1 ? 'true' : 'false',
            "is_cod" => $order_data['pay_type'] == 1 ? 'true' : 'false' ,  //是否是货到付款 true:是 false:否
            'distribution' => app_to_string( $order_data['sendTypeName'] ),  //配送方式
            "remark"=> app_to_string( $order_data['remark'] ),
            "customer"=>[
                "mobile"=> app_to_string( $order_data['custID'] ),
                "cust_id"=>app_to_string( $order_data['custID'] )
            ]
        ];

        /**
         * 交易优惠信息
         */
        $bill_push_data['promotions'][] =  [
            'type' 	 => '1' ,      //积分抵扣
            'promotions_amount' => app_to_decimal( $order_data['bill_points_money'] ) //订单积分抵扣金额
        ];
        $bill_push_data['promotions'][] =  [
            'type' 	 => '2',        //余额抵扣
            'promotions_amount' => app_to_decimal( $order_data['bill_balance_money'] ) //订单余额抵扣金额
        ];
        $bill_push_data['promotions'][] =  [
            'type' 	 => '3',        //优惠券抵扣
            'promotions_amount' => app_to_decimal( $order_data['bill_coupon_money'] ) //订单优惠券抵扣金额
        ];

        /**
         * 支付信息
         */
        $bill_push_data['payments'] = [];

        foreach( $bill_pay as &$pay ) { //支付方式

            if($pay > 0){
                //减去其他代支付的金额
                if( $pay['type'] == 1 ){
                    $pay['pay_amount'] = 0;
                }

                $bill_push_data['payments'][] = array(
                    'pay_name'   => app_to_string( $pay['payTypeName'] ), //支付方式名称
                    'pay_amount' => app_to_decimal( $pay['pay_amount'] )  //支付金额
                );
            }
        }

        if( $order_data['ziti'] == 0 ){ //送货上门

            //收货人信息
            $bill_push_data['receiver'] = [
                'receiver_name'   => app_to_string( $order_data['deliver_name'] ),
                'receiver_mobile' => app_to_string( $order_data['deliver_phone'] ),
                'country'          => '中国',
                'province'         => app_to_string( $order_data['deliver_province'] ),
                'city' 	  	        => app_to_string( $order_data['deliver_city'] ),
                'district'         => app_to_string( $order_data['deliver_county'] ),
                'street' 	        => empty( $order_data['zt_code'] ) ? app_to_string( $order_data['deliver_address'] ) : app_to_string( $order_data['deliver_address'] ).'  顾客自提地址：'.app_to_string( $order_data['zt_name'] )
            ];
        }else{ //门店自提

            //门店信息
            $bill_push_data['delivery'] = [
                'mall_code'       => app_to_string( $order_data['mallCode'] ),
                'mall_name'       => app_to_string( $order_data['mallName'] ),
                'mall_phone'      => $mall_master['phone'] != '' ? app_to_string( $mall_master['phone'] ) : app_to_string( $mall_master['mobile'] ),
                'mall_address'    => app_to_string( $mall_master['provinceName'] ) . app_to_string( $mall_master['cityName'] ) . app_to_string( $mall_master['countyName'] ) . app_to_string( $mall_master['address'] ),
                'mall_latitude'  => app_to_string( $mall_master['latitude'] ), //地理位置纬度
                'mall_longitude' => app_to_string( $mall_master['longitude'] ), //地理位置经度
            ];
        }
        /**
         * 商品明细
         */
        $bill_money = number_format( $order_data['bill_payable'] - $order_data['deliver_fee'],2,".","");

        foreach ( $bill_goods as &$good ) {

            //查询待发布商品表
            $goods_sale = GoodsSaleEdit::select('product_code','product_spec','goodsWeight')->where(['postID'=>$good['goods_postID'],'useFlg'=>1])->first();
            if( $goods_sale ) {
                $good['product_code'] = $goods_sale['product_code']; //商品编码
                $good['product_spec'] = $goods_sale['product_spec']; //商品规格
                $good['goods_weight']  = $goods_sale['goodsWeight']; //商品重量
            }
            unset( $goods_sale );

            //计算商品均摊总价
            $pay_amount = $bill_money * ( $good['goods_purchasePrice'] * $good['goods_amount'] / $order_data['bill_totalPaid'] );

            //商品计算方式 1.按数量 2.按重量 (不传默认按重量计算)
            $args_data['convey_goods_module'] = 1;
            $quantity = $good['goods_amount']; //销售数量

            if( $args_data['convey_goods_module'] == 2 ){  //按重量

                if( $good['goods_weight'] == 0 ){
                    $quantity = $good['goods_amount'];
                } else {
                    $quantity = number_format( $good['goods_amount'] * $good['goods_weight'] / 500,2,'.','');
                }

                //商品实售价格
                $good['goods_purchasePrice'] = number_format( $good['goods_purchasePrice'] * $good['goods_amount'] / $quantity ,2,'.','');
            }

            /**
            订单有两个商品A和B，A原价100，现价80，B原价120，现价110，购买2A+3B，整单优惠10元
            A商品明细的商品优惠=（100-80）*2=40
            B商品明细的商品优惠=（120-110）*3=30
            A的整单分摊优惠=10*（80*2）/（80*2+110*3）=3.27
            B的整单分摊优惠=10*（110*3）/（80*2+110*3）=6.73
             */

            //计算商品优惠金额
            $discount_amount = number_format( ( $good['goods_storePrice']- $good['goods_purchasePrice'])* $good['goods_amount'],2,".","");

            $apported_discount_amount = 0; //商品整单优惠金额

            if( $order_data['bill_totalPaid'] > 0  ){ //订单商品实际成交金额，不含运费，不含附加费
                //计算商品整单优惠金额
                $apported_discount_amount = ( $order_data['bill_points_money'] + $order_data['bill_coupon_money'])
                    * ( $good['goods_purchasePrice'] * $good['goods_amount'] / $order_data['bill_totalPaid']);
            }

            $bill_push_data['products'][] = [
                'order_seqno'  => app_to_string( $good['bill_goods_no'] ),
                'product_code' => app_to_string( $good['product_code'] ),
                'product_name' => app_to_string( $good['goods_name'] ),
                'market_price' => app_to_decimal( $good['goods_marketPrice'] ),
                'sale_price' => app_to_decimal( $good['goods_storePrice'] ),
                'unit_price' => app_to_decimal( number_format( $good['goods_purchasePrice'] / $good['product_spec'],2,".","") ),
                'discount_amount' => app_to_decimal( $discount_amount ), //商品优惠金额
                'apported_discount_amount' => app_to_decimal( number_format( $apported_discount_amount,2,".","") ),  //整单优惠分摊金额
                'product_num' => app_to_int( $quantity * $good['product_spec'] ),
                'product_total' =>  app_to_decimal( number_format( $quantity * $good['goods_purchasePrice'],2,".","") ),
                'product_pay_amount' => app_to_decimal( number_format( $pay_amount,2,".","") ),
                'barcode' => app_to_string( $good['product_code'] )  //条形码
            ];
        }


        return response()->json(['code' => 200, 'message' =>'ok','data' => $bill_push_data]);
    }


    /**
     * 批量获取订单接口
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function batchGet( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号
        $page = $request->input('page'); //页码
        $limit = $request->input('limit'); //每页显示条数
        $sortname = $request->input('sortname'); //排序字段
        $sortorder = $request->input('sortorder'); //排序方式
        $start_time = $request->input('start_time'); //下单开始时间
        $end_time = $request->input('end_time'); //下单开始时间

        if ( empty( $page ) ) { //页码,不传默认为1
            $page = 1;
        }
        if ( empty( $limit ) ) { //每页显示条数,不传默认为10
            $limit = 10;
        }
        if ( empty( $sortname ) ) { //排序字段(默认按订单号)
            $sortname = 'bill_no';
        }
        if ( empty( $sortorder ) ) { //排序方式(默认按desc)
            $sortorder = 'desc';
        }

        $where = [];

        //订单号存在且不为空,根据订单号条件查询
        if ( !empty( $order_no ) ) {
            $where[] = ['bill_no',$order_no];
        }

        //下单开始时间存在且不为空,根据下单开始时间条件查询
        if ( !empty( $start_time ) ) {
            $where[] = ['start_time',$start_time];
        }

        //下单结束时间存在且不为空,根据下单结束时间条件查询
        if ( !empty( $end_time ) ) {
            $where[] = ['end_time',$end_time];
        }

        //查询订单信息
        $bill_master = Bill::where($where)
                       ->orderBy( $sortname, $sortorder )
                       ->paginate( $limit )
                       ->toArray();

        $order_array = []; //返回订单列表信息

        if ( !empty( $bill_master ) ) {

            foreach ( $bill_master['data'] as &$order_data ) {

                //根据门店id查询门店信息
                $mall_master = MallMaster::find( $order_data['mallID'] );
                if ( !$mall_master ) {
                    return response()->json(['code' => 100001, 'message' => '门店信息不存在']);
                }

                //根据订单号查询订单商品信息
                $bill_goods = BillGoods::where(['bill_no' => $order_data['bill_no']])->get()->toArray();
                if ( !$bill_goods ) {
                    return response()->json(['code' => 100002, 'message' => '订单商品信息不存在']);
                }

                //根据订单号查询订单支付信息
                $bill_pay = BillPay::select('payTypeName', 'pay_time', 'pay_amount', 'pay_code', 'type', 'payTypeID')
                    ->where(['bill_no' => $order_data['bill_no']])->get()->toArray();
                if ( !$bill_pay ) {
                    return response()->json(['code' => 100003, 'message' => '订单支付信息不存在']);
                }

                //推送数据数组
                $bill_push_data = [
                    "order_no" => app_to_string( $order_data['bill_no'] ),
                    "shop_code" => 'WDH',
                    "create_time" => app_to_string( $order_data['createTime'] ),
                    "pay_state" => app_to_int( $order_data['pay_status'] ),
                    "pay_time" => app_to_string( $order_data['payed_time'] ),
                    "total" => app_to_decimal( $order_data['bill_totalMoney'] ),
                    "freight" => app_to_decimal( $order_data['deliver_fee'] ),
                    "require_invoice" => $order_data['invoice'] == 1 ? 'true' : 'false', //是否开发票  true:是,false:否
                    "is_cod" => $order_data['pay_type'] == 1 ? 'true' : 'false',  //是否货到付款  true:是,false:否
                    'distribution' => app_to_string( $order_data['sendTypeName'] ),  //配送方式
                    "remark" => app_to_string( $order_data['remark'] ),
                    "customer" => [
                        "mobile" => app_to_string( $order_data['custID'] ),
                        "cust_id" => app_to_string( $order_data['custID'] )
                    ]
                ];

                /**
                 * 交易优惠信息
                 */
                $bill_push_data['promotions'][] =  [
                    'type' 	 => '1' ,      //积分抵扣
                    'promotions_amount' => app_to_decimal( $order_data['bill_points_money'] ) //订单积分抵扣金额
                ];
                $bill_push_data['promotions'][] =  [
                    'type' 	 => '2',        //余额抵扣
                    'promotions_amount' => app_to_decimal( $order_data['bill_balance_money'] ) //订单余额抵扣金额
                ];
                $bill_push_data['promotions'][] =  [
                    'type' 	 => '3',        //优惠券抵扣
                    'promotions_amount' => app_to_decimal( $order_data['bill_coupon_money'] ) //订单优惠券抵扣金额
                ];

                /**
                 * 支付信息
                 */
                $bill_push_data['payments'] = [];

                foreach ( $bill_pay as &$pay ) { //支付方式

                    if ( $pay > 0 ) {
                        //减去其他代支付的金额
                        if ( $pay['type'] == 1 ) {
                            $pay['pay_amount'] = 0;
                        }

                        $bill_push_data['payments'][] = [
                            'pay_name' => app_to_string( $pay['payTypeName'] ), //支付方式名称
                            'pay_amount' => app_to_decimal( $pay['pay_amount'] ) //支付金额
                        ];
                    }
                }

                if ( $order_data['ziti'] == 0 ) { //送货上门

                    //收货人信息
                    $bill_push_data['receiver'] = [
                        'receiver_name' => app_to_string( $order_data['deliver_name'] ),
                        'receiver_mobile' => app_to_string( $order_data['deliver_phone'] ),
                        'country' => '中国',
                        'province' => app_to_string( $order_data['deliver_province'] ),
                        'city' => app_to_string( $order_data['deliver_city'] ),
                        'district' => app_to_string( $order_data['deliver_county'] ),
                        'street' => empty( $order_data['zt_code'] ) ? app_to_string( $order_data['deliver_address'] ) : app_to_string( $order_data['deliver_address'] ) . '  顾客自提地址：' . app_to_string( $order_data['zt_name'] )
                    ];
                } else { //门店自提

                    //门店信息
                    $bill_push_data['delivery'] = [
                        'mall_code' => app_to_string( $order_data['mallCode'] ),
                        'mall_name' => app_to_string( $order_data['mallName'] ),
                        'mall_phone' => $mall_master['phone'] != '' ? app_to_string( $mall_master['phone'] ) : app_to_string( $mall_master['mobile'] ),
                        'mall_address' => app_to_string( $mall_master['provinceName'] ) . app_to_string( $mall_master['cityName'] ) . app_to_string( $mall_master['countyName'] ) . app_to_string( $mall_master['address'] ),
                        'mall_latitude' => app_to_string( $mall_master['latitude'] ), //地理位置纬度
                        'mall_longitude' => app_to_string( $mall_master['longitude'] ), //地理位置经度
                    ];
                }

                /**
                 * 商品明细
                 */
                $bill_money = number_format( $order_data['bill_payable'] - $order_data['deliver_fee'], 2, ".", "");

                foreach ( $bill_goods as &$good ) {

                    //查询待发布商品表
                    $goods_sale = GoodsSaleEdit::select('product_code', 'product_spec', 'goodsWeight')->where(['postID' => $good['goods_postID'], 'useFlg' => 1])->first();
                    if( $goods_sale ) {
                        $good['product_code'] = $goods_sale['product_code']; //商品编码
                        $good['product_spec'] = $goods_sale['product_spec']; //商品规格
                        $good['goods_weight']  = $goods_sale['goodsWeight']; //商品重量
                    }
                    unset( $goods_sale );

                    //计算商品均摊总价
                    $pay_amount = $bill_money * ( $good['goods_purchasePrice'] * $good['goods_amount'] / $order_data['bill_totalPaid'] );

                    //商品计算方式 1.按数量 2.按重量 (默认按数量计算)
                    $args_data['convey_goods_module'] = 1;
                    $quantity = $good['goods_amount']; //销售数量

                    if ( $args_data['convey_goods_module'] == 2 ) {  //按重量

                        if ( $good['goods_weight'] == 0) {
                            $quantity = $good['goods_amount'];
                        } else {
                            $quantity = number_format( $good['goods_amount'] * $good['goods_weight'] / 500, 2, '.', '');
                        }

                        //商品实售价格
                        $good['goods_purchasePrice'] = number_format( $good['goods_purchasePrice'] * $good['goods_amount'] / $quantity, 2, '.', '');
                    }

                    /**
                     * 订单有两个商品A和B，A原价100，现价80，B原价120，现价110，购买2A+3B，整单优惠10元
                     * A商品明细的商品优惠=（100-80）*2=40
                     * B商品明细的商品优惠=（120-110）*3=30
                     * A的整单分摊优惠=10*（80*2）/（80*2+110*3）=3.27
                     * B的整单分摊优惠=10*（110*3）/（80*2+110*3）=6.73
                     */

                    //计算商品优惠金额
                    $discount_amount = number_format(( $good['goods_storePrice'] - $good['goods_purchasePrice']) * $good['goods_amount'], 2, ".", "");

                    //商品整单优惠金额
                    $apported_discount_amount = 0;

                    if ( $order_data['bill_totalPaid'] > 0 ) { //订单商品实际成交金额，不含运费，不含附加费
                        //计算商品整单优惠金额
                        $apported_discount_amount = ( $order_data['bill_points_money'] + $order_data['bill_coupon_money'])
                            * ( $good['goods_purchasePrice'] * $good['goods_amount'] / $order_data['bill_totalPaid']);
                    }

                    $bill_push_data['products'][] = [
                        'order_seqno' => app_to_string( $good['bill_goods_no'] ),
                        'product_code' => app_to_string( $good['product_code'] ),
                        'product_name' => app_to_string( $good['goods_name'] ),
                        'market_price' => app_to_decimal( $good['goods_marketPrice'] ),
                        'sale_price' => app_to_decimal( $good['goods_storePrice'] ),
                        'unit_price' => app_to_decimal(number_format( $good['goods_purchasePrice'] / $good['product_spec'], 2, ".", "")),
                        'discount_amount' => app_to_decimal( $discount_amount ), //商品优惠金额
                        'apported_discount_amount' => app_to_decimal(number_format( $apported_discount_amount, 2, ".", "") ),  //整单优惠分摊金额
                        'product_num' => app_to_int( $quantity * $good['product_spec'] ),
                        'product_total' => app_to_decimal(number_format( $quantity * $good['goods_purchasePrice'], 2, ".", "") ),
                        'product_pay_amount' => app_to_decimal(number_format( $pay_amount, 2, ".", "") )
                    ];
                }

                $order_array[] = $bill_push_data;
            }

        }

        $data = [
            'total' => $bill_master['total'] ? $bill_master['total'] : 0,
            'list' => $order_array
        ];


        return response()->json(['code' => 200, 'message' =>'ok', 'data'=> $data]);
    }


    /**
     * 获取退货单接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function returnGet( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数order_no不能为空']);
        }

        //根据订单号查询订单信息
        $order_data = Bill::find( $order_no );
        if ( !$order_data ) {
            return response()->json(['code' => 100002, 'message' =>'订单信息不存在']);
        }

        //根据订单号查询退货单信息
        $bill_return_data = BillReturn::select('custID','return_no','return_status','return_reason','createTime','refund_account')
                            ->where( ['bill_no'=>$order_no] )->first();
        if ( !$bill_return_data ) {
            return response()->json(['code' => 100003, 'message' =>'订单退货信息不存在']);
        }

        //根据订单号查询订单商品信息
        $bill_goods = BillGoods::where( ['bill_no'=>$order_no] )->get()->toArray();
        if ( !$bill_goods ) {
            return response()->json(['code' => 100004, 'message' =>'订单商品信息不存在']);
        }

        //根据订单号查询订单支付信息
        $bill_pay = BillPay::where( ['bill_no'=>$order_no] )->get()->toArray();
        if ( !$bill_pay ) {
            return response()->json(['code' => 100005, 'message' =>'订单支付信息不存在']);
        }

        //订单商品
        $bill_goods_array = [];

        foreach ( $bill_goods as &$bill ) {

            $temp_goods = [
                'product_code' => $bill['product_code'], //商品编码
                'goods_name' => $bill['goods_name'], //商品名称
                'goods_amount' => $bill['goods_amount'], //销售数量
                'goods_storePrice' => $bill['goods_storePrice'], //销售价格
                'goods_purchasePrice' => $bill['goods_purchasePrice'], //实售价格
                'goods_marketPrice' => $bill['goods_marketPrice'], //市场价格
                'goods_pointsPrice' => $bill['goods_pointsPrice'], //积分价格
                'product_spec' => '1.00', //商品规格
                'goodsWeight' => 0 //商品重量
            ];

            //查询待发布商品表
            $goods_sale = GoodsSaleEdit::select('product_code','product_spec','goodsWeight')->where(['postID'=>$bill['goods_postID'],'useFlg'=>1])->first();
            if( $goods_sale ) {
                $good['product_code'] = $goods_sale['product_code']; //商品编码
                $good['product_spec'] = $goods_sale['product_spec']; //商品规格
                $good['goods_weight']  = $goods_sale['goodsWeight']; //商品重量
            }

            $bill_goods_array[] = $temp_goods;
            unset( $temp_goods );
            unset( $goods_sale );

        }

        //退款金额 总金额
        $total = 0;

        //主支付方式
        $payType = $order_data['pay_type'];

        //支付明细
        $pay_array = [];

        foreach ( $bill_pay as &$pay ) {

            if ( $pay['payTypeID'] == 1 ) { //货到付款方式 不统计
                continue;
            } else if ( $pay['payTypeID'] == 3 ) { //积分抵扣
                $amount = $pay['pay_amount'];
            }else{
                $amount = $pay['pay_amount'];
            }

            $pay_array[] = [
                'payment_type'=> app_to_string( $pay['payTypeName'] ),
                'refund_account'=>isset( $bill_return_data['refund_account'] ) && !empty( $bill_return_data['refund_account']) ? app_to_string( $bill_return_data[0]['refund_account'] ) :'123456',
                'refund_price'=> app_to_decimal( $amount ),
            ];

            $total += $amount;
        }

        //商品明细
        $goods_array = [];

        foreach ( $bill_goods_array as $goods ) {

            $goods_avg_price = $total * ( $goods['goods_purchasePrice'] / $order_data['bill_totalPaid'] );

            //商品计算方式 1.按数量 2.按重量 (默认按数量)
            $args_data['convey_goods_module'] = 1;
            $quantity = $goods['goods_amount']; //销售数量

            if ( $args_data['convey_goods_module'] == 2 ) {  //按重量

                if( $goods['goods_weight'] == 0 ) {
                    $quantity = $goods['goods_amount'];
                } else {
                    $quantity = number_format( $goods['goods_amount'] * $goods['goods_weight'] / 500,2,'.','');
                }

                $goods_avg_price = number_format( $goods_avg_price * $goods['goods_amount'] / $quantity ,2,'.','');
            }

            $product_code = trim( $goods['product_code'] ); //商品编码

            if ( $product_code == '' ) {
                $product_code = '-';
            }

            $goods_array[] = [
                "product_code" => app_to_string( $product_code ),    //货号
                "product_name" => app_to_string( $goods['goods_name'] ),   //商品名称
                "unit_price" => app_to_decimal( number_format( $goods_avg_price / $goods['product_spec'],2,".",".") ), //单价
                "product_num" => app_to_int( $quantity * $goods['product_spec'] ),  //数量
                "product_total" => $payType == 1 ? 0 : app_to_decimal( number_format( $goods_avg_price * $quantity,2,".",".") )   //总价,货到付款方式时 ,退款金额为0
            ];
        }

        //会员信息
        $customer_array = [
            'mobile'=> app_to_string( $bill_return_data['custID'] ), //会员手机号
            'name'=> app_to_string( $bill_return_data['custID'] ) //会员名
        ];

        //请求全部参数
        $request_params = [
            'return_order_no'=> app_to_string( $bill_return_data['return_no'] ),    //退款编号
            'shop_code'=>'WDH',   //店铺代码
            'sale_order_no'=> app_to_string( $args_data['order_no'] ),     //订单号
            'return_order_status'=> app_to_int( $bill_return_data['return_status'] ),     //状态  1：未处理 2：已处理 3：已完成 4：已废弃
            'create_time'=> app_to_string( $bill_return_data['createTime'] ), //创建时间
            'return_reason'=> app_to_string( $bill_return_data['return_reason'] ),  //申请原因
            'total'=> app_to_decimal( $total ),     //退款金额 必须大于等于0(含余额) Payment中所有amount总和加上balance必须等于total
            'customer'=>$customer_array,      //顾客信息
            'products'=>$goods_array,     //商品明细
            'payments'=>$pay_array     //支付明细
        ];

        return response()->json(['code' => 200, 'message' =>'ok', 'data' =>$request_params]);
    }


    /**
     * 退货单审核接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function returnAudit( Request $request )
    {

        $order_no = $request->input('order_no'); //订单号
        $refunds_no = $request->input('refunds_no'); //退款单号

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数order_no不能为空']);
        }
        //订单号
        if ( empty( $refunds_no ) ) {
            return response()->json(['code' => 100002, 'message' =>'参数refunds_no不能为空']);
        }

        //根据订单号查询订单信息
        $order_data = Bill::find( $order_no );
        if ( !$order_data ) {
            return response()->json(['code' => 100003, 'message' =>'订单信息不存在']);
        }

        //根据退款单号查询退货单信息
        $return_data = BillReturn::find( $refunds_no );
        if ( !$return_data ) {
            return response()->json(['code' => 100004, 'message' =>'订单退货信息不存在']);
        }

        //退货状态：1、未处理 2、已审核 3、已完成 4.已取消
        if ( $return_data['return_status'] == 2 ) {
            return response()->json(['code' => 100005, 'message' =>'订单已审核']);
        }
        if ( $return_data['return_status'] == 3 ) {
            return response()->json(['code' => 100006, 'message' =>'订单已完成']);
        }
        if ( $return_data['return_status'] == 4 ) {
            return response()->json(['code' => 100007, 'message' =>'订单已取消']);
        }

        try {

            //开启事务
            DB::beginTransaction();

            //更新退货单主表订单状态为已审核
            $bill_return = BillReturn::where(['return_no'=>$refunds_no])->update(['return_status'=>2,'confirm_time'=>Carbon::now(),'confirmor'=>'api']);

            /**
             * 更新订单主表订单状态
             * bill_status订单状态:0、建立 1、确认 2、发货 3、配送 4、完成 5、取消 6、异常 7、配货中 8、配货完成
             * bill_return_status 状态：1、未审核 2、已审核 3、已完成 4、已取消 5、已退款
             */
            $bill_master = Bill::where(['bill_no'=>$order_no])->update(['bill_status'=>5,'bill_return_status'=>2]);

            if ( $bill_master <= 0 || $bill_return <= 0 ) {
                return response()->json(['code' => 100008, 'message' =>'订单状态更新失败']);
            }

            //推送订单创建成功消息模板
            $push_array = [
                'template_scene_id' => '10016',
                'bill_status' => '7',
                'bill_no' => $order_no,
                'return_no' => $refunds_no
            ];
            ApiService::billMessageTemplate( $push_array );

            //异步推送传入ERP处理
            self::pushBillToErp([
                    'bill_status'=> 10,
                    'bill_no'=> $order_no,
                    'remark'=> $refunds_no
                ]);

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100009, 'message' => '退货单审核失败']);
        }


        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 退货单取消接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function returnCancel( Request $request )
    {

        $return_no = $request->input('return_no'); //退货单号
        $cancel_reason = $request->input('cancel_reason'); //订单号

        //退货单号
        if ( empty( $return_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数return_no不能为空']);
        }

        //取消原因
        if ( empty( $cancel_reason ) ) {
            return response()->json(['code' => 100002, 'message' =>'参数cancel_reason不能为空']);
        }

        //根据退货单号查询退货单信息
        $return_data = BillReturn::find( $return_no );

        if ( !$return_data ) {
            return response()->json(['code' => 100003, 'message' =>'订单退货信息不存在']);
        }

        //退货状态：1、未处理 2、已审核 3、已完成 4.已取消
        if ( $return_data['return_status'] == 3 ) {
            return response()->json(['code' => 100004, 'message' =>'订单已完成']);
        }
        if ( $return_data['return_status'] == 4 ) {
            return response()->json(['code' => 100005, 'message' =>'订单已取消']);
        }

        /**
         * 更新退货单状态
         * return_status 状态：1、未审核 2、已审核 3、已完成 4、已取消 5、已退款
         */
        $bill_return = BillReturn::where(['return_no'=>$return_no])->update(['return_status'=>4,'not_through_reason'=>$cancel_reason]);
        if ( $bill_return <= 0 ) {
            return response()->json(['code' => 100006, 'message' =>'退货单状态更新失败']);
        }

        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 退货单完成接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function returnFinish( Request $request )
    {

        $return_no = $request->input('return_no'); //退货单号

        //退货单号
        if ( empty( $return_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数return_no不能为空']);
        }

        //根据退货单号查询退货单信息
        $return_data = BillReturn::find( $return_no );
        if ( !$return_data ) {
            return response()->json(['code' => 100002, 'message' =>'订单退货信息不存在']);
        }

        //退货状态：1、未处理 2、已审核 3、已完成 4.已取消
        if ( $return_data['return_status'] == 1 ) {
            return response()->json(['code' => 100003, 'message' =>'退货单未审核']);
        }
        if ( $return_data['return_status'] == 3 ) {
            return response()->json(['code' => 100004, 'message' =>'退货单已完成']);
        }
        if ( $return_data['return_status'] == 4 ) {
            return response()->json(['code' => 100005, 'message' =>'退货单已取消']);
        }

        //根据订单号查询订单信息
        $bill_master = Bill::find( $return_data['bill_no'] );
        if ( !$bill_master ) {
            return response()->json(['code' => 100006, 'message' =>'订单信息不存在']);
        }

        //根据订单号查询订单支付信息
        $bill_pay = BillPay::where( ['bill_no'=>$return_data['bill_no']] )->get()->toArray();;
        if ( !$bill_pay ) {
            return response()->json(['code' => 100007, 'message' =>'订单支付信息不存在']);
        }

        //退货的在线支付数组
        $online_pay_data = [];

        //退回的积分数组
        $points_data = [];

        //退货的余额数组
        $balance_data = [];

        //货到付款退款
        $refund_amount = 0;

        foreach ( $bill_pay as &$pay ) {

            $pay['auto_refund'] = 0; //在线支付方式是否支持自动退款：0、否 1、是

            // type支付方式类型：1、货到付款 2、在线支付 3、汇款 4、余额 5、积分
            if ( $pay['type'] == 1 ) {
                if ( $bill_master['bill_status'] == 4 ) { //订单状态为已完成
                    $refund_amount = $return_data['return_price'];
                    //退款金额
                    $refund_amount -= $pay['pay_amount'];
                    if( $refund_amount > 0 ){
                        $refund_amount = $pay['pay_amount']; //支付数额
                    }
                }
            } else if ( $pay['type'] == 2 ) {
                $refund_amount = $return_data['return_price'];
                //查询支付方式表
                $pay_type = SysPaytype::select('auto_refund')->find( $pay['payTypeID'] );
                if ( $pay_type ) {
                    $pay['auto_refund'] = $pay_type['auto_refund'];
                }
                $online_pay_data = $pay;

            } else if ( $pay['type'] == 4 ) {
                $balance_data = [
                    'amount' => $pay['pay_amount'],
                    'remark' => '订单' . $return_data['bill_no'] . '退货，退回余额'
                ];
            } else if ( $pay['type'] == 5 ) {
                $points_data = [
                    'points' => $pay['pay_amount'],
                    'remark' => '订单' . $return_data['bill_no'] . '退货，退回积分'
                ];
            }
        }

        try {

            //开启事务
            DB::beginTransaction();

            /**
             * 更新退货单状态
             * return_status 状态：1、未审核 2、已审核 3、已完成 4、已取消 5、已退款
             */
            $bill_return = BillReturn::where(['return_no'=>$return_no])->update(['return_status'=>3]);
            if ( $bill_return <= 0 ) {
                return response()->json(['code' => 100008, 'message' =>'退货单状态更新失败']);
            }

            //退回余额
            $return_balance_money = 0.00;
            if ( $bill_master['bill_balance_money'] > 0 && $refund_amount > 0 ) { //订单余额抵扣金额大于0 并且退款金额大于0
                $return_balance_money = $refund_amount;
                $refund_amount -= $bill_master['bill_balance_money'];
                if( $refund_amount > 0 ){
                    $return_balance_money = $bill_master['bill_balance_money'];
                }
            }

            //退回积分
            $return_points = 0;
            if ( ( $bill_master['bill_points_money'] > 0 || $bill_master['bill_pointsPrice'] > 0) && $refund_amount > 0 ) { //订单积分抵扣金额大于0 或者订单总积分价格大于0
                //查询积分兑换比例配置
                $points_rate    = ConfigureFunction::getConfigureField(2, 'points_exchange_ratio');
                $return_points  = $refund_amount * $points_rate;
                $return_points -= ( $bill_master['bill_points_money'] * $points_rate + $bill_master['bill_pointsPrice'] );
                if( $return_points < 0 ){
                    return response()->json(['code' => 100009, 'message' =>'订单支付额不足以退款']);
                }
            }

            //保存退款单信息
            $bill_refund = new BillRefund;
            $bill_refund->uuid = makeUuid();
            $bill_refund->timeStamp = Carbon::now();
            $bill_refund->creator = 'api'; //创建人
            $bill_refund->createTime = Carbon::now();
            $bill_refund->bill_no = $bill_master['bill_no']; //订单号
            $bill_refund->refund_status = empty( $online_pay_data ) ? 1 : 2;
            $bill_refund->return_no = $return_no; //退货单号
            $bill_refund->custID = $bill_master['custID'];         //会员名
            $bill_refund->pcustID = $bill_master['pcustID'];      //会员号
            $bill_refund->refund_source = 1; //退款来源：1、订单退货 2、订单取消 3、订单退款 4、手工退款
            $bill_refund->mobile = $bill_master['deliver_mobile'];               //联系手机
            $bill_refund->refund_payee = $bill_master['deliver_name'];          //联系人
            $bill_refund->refund_type = empty( $online_pay_data ) ? 1 : 2;
            $bill_refund->refund_amount = $refund_amount; //退款金额
            $bill_refund->confirmor = 'api';
            $bill_refund->confirm_time = Carbon::now();
            $bill_refund->return_balance = $return_balance_money; //退回余额
            $bill_refund->return_points = $return_points; //退回积分
            $bill_refund->refund_onlinepay_status = empty( $online_pay_data ) ? 0 : 2; //在线支付退款状态：0、无退款 1、等待退款 2、正在退款 3、已退款 4、退款失败
            $bill_refund->refund_reason_id = 0;  //退款原因ID
            $bill_refund->refund_reason = '订单退货'; //退款原因
            $bill_refund->mallID = $bill_master['mallID']; //门店ID
            $bill_refund->mallCode = $bill_master['mallCode']; //门店编号
            $bill_refund->mallName = $bill_master['mallName']; //门店名称
            $bill_refund->payTypeID = $bill_master['payTypeID']; //支付方式ID
            $bill_refund->payTypeName = $bill_master['payTypeName']; //支付方式名称
            $bill_refund->save();

            //退款操作
            if ( !empty( $points_data ) || !empty( $online_pay_data ) || !empty( $balance_data ) ) {

                //根据会员号查询会员信息
                $cust_data = Customer::select('pcustID','custID','cardNo')->find( $bill_master['pcustID'] );

                //退回积分
                if ( $return_points > 0 ) {

                    $args_points = [
                        'pcustID' => $cust_data['pcustID'],
                        'custID' => $cust_data['custID'],
                        'cardNo' => $cust_data['cardNo'],
                        'points' => $points_data['points'],
                        'remark' => $points_data['remark']
                    ];
                    $points_result = WdhService::pointsAdd( $args_points );
                    if ( $points_result['code'] != 200 ) {
                        return response()->json(['code' => 100010, 'message' =>'积分退回失败']);
                    } else {
                        self::trace( $return_no , '积分退回成功',null);
                    }
                }

                //退回余额
                if ( !empty( $balance_data ) ) {

                    $args_balance = [
                        'pcustID' => $cust_data['pcustID'],
                        'custID' => $cust_data['custID'],
                        'cardNo' => $cust_data['cardNo'],
                        'amount' => $balance_data['amount'],
                        'remark' => $balance_data['remark']
                    ];
                    $balance_result = WdhService::recharge( $args_balance );
                    if ( $balance_result['code'] != 200 ) {
                        return response()->json(['code' => 100011, 'message' =>'余额退回失败']);
                    } else {
                        self::trace( $return_no , '余额退回成功',null);
                    }
                }

                //退回微信支付、支付宝等
                if ( !empty( $online_pay_data ) ) {

                    //根据订单号查询订单信息
                    $bill_data = bill::select('split_type','parent_bill_no','bill_payable','billChannel')->find( $online_pay_data['bill_no'] );
                    if ( !$bill_data ) {
                        return response()->json(['code' => 100012, 'message' =>'订单信息不存在']);
                    }

                    $refund_id = 0;

                    $bill_no = $online_pay_data['bill_no'];
                    if ( $bill_data['split_type'] == 3 ) {  //订单为子订单
                        $bill_no = $bill_data['parent_bill_no'];
                    }
                    $channelType = '08';//银联渠道类型
                    if ( $bill_data['billChannel'] == 3 ) {
                        $channelType = '07';
                    }

                    $pay_data = BillPay::select('deduct_amount')->where(['bill_no'=>$bill_no,'payTypeID'=>$online_pay_data['payTypeID']])->get()->toArray();
                    if ( $online_pay_data['payTypeID'] == 6 ) {  //支付方式为"代付"
                        $online_pay_data['payTypeID'] = 5;
                    }

                    //支付参数
                    $args_data = [
                        'payTypeID' => $online_pay_data['payTypeID'],
                        'transaction_id' => $online_pay_data['pay_code'],
                        'out_trade_no' => $bill_no,
                        'out_refund_no' => $return_no,
                        'total_fee' => $pay_data[0]['deduct_amount'],
                        'refund_fee' => $online_pay_data['deduct_amount'],
                        'refund_reason' => '订单退货',
                        'channelType' => $channelType
                    ];

                    if ( $online_pay_data['payTypeID'] == 4 ) {  //支付宝退款
                        $return_data = WdhService::alipayRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 5 ) {  //微信退款
                        $return_data = WdhService::weixinRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 7 ) {  //百付宝退款
                        $return_data = WdhService::baifubaoRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 8 ) {  //银联退款
                        $return_data = WdhService::unionpayRefund( $args_data );
                    } else {
                        $return_data = [ 'code' => 100013 , 'message' =>'支付方式有误' ];
                    }

                    if ( $return_data['code'] == 200 || $return_data['data']['code'] == 200 ) {

                        if ( isset( $return_data['data']['refund_id']) && !empty( $return_data['data']['refund_id'] ) ) {
                            $refund_id = $return_data['data']['refund_id'];
                        }
                    }

                    self::trace( $return_no , '金额退回中',null);

                    if ( !empty( $refund_id ) ) {
                        BillRefund::where(['refund_no'=>$return_no])->update(['refund_id'=>$refund_id]);
                    }
                }
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100014, 'message' => '退货单完成失败']);
        }


        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 退货单快速完成接口
     * @param Request $request
     * @return array|\Illuminate\Http\JsonResponse
     */
    public function returnFastFinish( Request $request )
    {

        $return_no = $request->input('return_no'); //退货单号

        //退货单号
        if ( empty( $return_no ) ) {
            return response()->json(['code' => 100001, 'message' =>'参数return_no不能为空']);
        }

        //根据退货单号查询退货单信息
        $return_data = BillReturn::find( $return_no );
        if ( !$return_data ) {
            return response()->json(['code' => 100002, 'message' =>'订单退货信息不存在']);
        }

        //退货状态：1、未处理 2、已审核 3、已完成 4.已取消
        if ( $return_data['return_status'] == 3 ) {
            return response()->json(['code' => 100003, 'message' =>'退货单已完成']);
        }
        if ( $return_data['return_status'] == 4 ) {
            return response()->json(['code' => 100004, 'message' =>'退货单已取消']);
        }

        //查询订单信息
        $bill_master = Bill::find( $return_data['bill_no'] );
        if ( !$bill_master ) {
            return response()->json(['code' => 100005, 'message' =>'订单信息不存在']);
        }

        //查询订单支付信息
        $bill_pay = BillPay::where( ['bill_no'=>$return_data['bill_no']] )->get()->toArray();;
        if ( !$bill_pay ) {
            return response()->json(['code' => 100006, 'message' =>'订单支付信息不存在']);
        }

        //退货的在线支付数组
        $online_pay_data = [];

        //退回的积分数组
        $points_data = [];

        //退货的余额数组
        $balance_data = [];

        //货到付款退款
        $refund_amount = 0;

        foreach ( $bill_pay as &$pay ) {

            $pay['auto_refund'] = 0; //在线支付方式是否支持自动退款：0、否 1、是

            // type支付方式类型：1、货到付款 2、在线支付 3、汇款 4、余额 5、积分
            if ( $pay['type'] == 1 ) {
                if ( $bill_master['bill_status'] == 4 ) {  //订单状态为已完成
                    $refund_amount = $return_data['return_price'];
                    //退款金额
                    $refund_amount -= $pay['pay_amount'];
                    if( $refund_amount > 0 ){
                        $refund_amount = $pay['pay_amount']; //支付数额
                    }
                }
            } else if ( $pay['type'] == 2 ) {
                $refund_amount = $return_data['return_price'];
                //查询支付方式表
                $pay_type = SysPaytype::select('auto_refund')->find( $pay['payTypeID'] );
                if ( $pay_type ) {
                    $pay['auto_refund'] = $pay_type['auto_refund'];
                }
                $online_pay_data = $pay;

            } else if ( $pay['type'] == 4 ) {
                $balance_data = [
                    'amount' => $pay['pay_amount'],
                    'remark' => '订单' . $return_data['bill_no'] . '退货，退回余额'
                ];
            } else if ( $pay['type'] == 5 ) {
                $points_data = [
                    'points' => $pay['pay_amount'],
                    'remark' => '订单' . $return_data['bill_no'] . '退货，退回积分'
                ];
            }
        }

        try {

            //开启事务
            DB::beginTransaction();

            /**
             * 更新退货单状态
             * return_status 状态：1、未审核 2、已审核 3、已完成 4、已取消 5、已退款
             */
            $bill_return = BillReturn::where(['return_no'=>$return_no])->update(['return_status'=>3]);
            if ( $bill_return <= 0 ) {
                return response()->json(['code' => 100008, 'message' =>'退货单状态更新失败']);
            }

            //退回余额
            $return_balance_money = 0;
            if ( $bill_master['bill_balance_money'] > 0 && $refund_amount > 0 ) {  //订单余额抵扣金额大于0 并且退款金额大于0
                $return_balance_money = $refund_amount;
                $refund_amount -= $bill_master['bill_balance_money'];
                if ( $refund_amount > 0 ) {
                    $return_balance_money = $bill_master['bill_balance_money'];
                }
            }

            //退回积分
            $return_points = 0;
            if ( ( $bill_master['bill_points_money'] > 0 || $bill_master['bill_pointsPrice'] > 0) && $refund_amount > 0 ) { //订单积分抵扣金额大于0 或者订单总积分价格大于0
                //查询积分兑换比例配置
                $points_exchange_ratio = ConfigureFunction::getConfigureField(2, 'points_exchange_ratio');
                $return_points  = $refund_amount * $points_exchange_ratio;
                $return_points -= ( $bill_master['bill_points_money'] * $points_exchange_ratio + $bill_master['bill_pointsPrice'] );
                if( $return_points < 0 ) {
                    return response()->json(['code' => 100009, 'message' =>'订单支付额不足以退款']);
                }
            }

            //保存退款单信息
            $bill_refund = new BillRefund;
            $bill_refund->uuid = makeUuid();
            $bill_refund->timeStamp = Carbon::now();
            $bill_refund->creator = 'api'; //创建人
            $bill_refund->createTime = Carbon::now();
            $bill_refund->bill_no = $bill_master['bill_no']; //订单号
            $bill_refund->refund_status = empty( $online_pay_data ) ? 1 : 2;
            $bill_refund->return_no = $return_no; //退货单号
            $bill_refund->custID = $bill_master['custID']; //会员名
            $bill_refund->pcustID = $bill_master['pcustID']; //会员号
            $bill_refund->refund_source = 1; //退款来源：1、订单退货 2、订单取消 3、订单退款 4、手工退款
            $bill_refund->mobile = $bill_master['deliver_mobile']; //联系手机
            $bill_refund->refund_payee = $bill_master['deliver_name']; //联系人
            $bill_refund->refund_type = empty( $online_pay_data ) ? 1 : 2;
            $bill_refund->refund_amount = $refund_amount; //退款金额
            $bill_refund->confirmor = 'api';
            $bill_refund->confirm_time = Carbon::now();
            $bill_refund->return_balance = $return_balance_money; //退回余额
            $bill_refund->return_points = $return_points; //退回积分
            $bill_refund->refund_onlinepay_status = empty( $online_pay_data ) ? 0 : 2; //在线支付退款状态：0、无退款 1、等待退款 2、正在退款 3、已退款 4、退款失败
            $bill_refund->refund_reason_id = 0; //退款原因ID
            $bill_refund->refund_reason = '订单退货'; //退款原因
            $bill_refund->mallID = $bill_master['mallID']; //门店ID
            $bill_refund->mallCode = $bill_master['mallCode']; //门店编号
            $bill_refund->mallName = $bill_master['mallName']; //门店名称
            $bill_refund->payTypeID = $bill_master['payTypeID']; //支付方式ID
            $bill_refund->payTypeName = $bill_master['payTypeName']; //支付方式名称
            $bill_refund->save();

            //退款操作
            if ( !empty( $points_data ) || !empty( $online_pay_data ) || !empty( $balance_data ) ) {

                $cust_data = Customer::find( $bill_master['pcustID'] );

                //退回积分
                if ( $return_points > 0 ) {

                    $args_points = [
                        'pcustID' => $cust_data['pcustID'],
                        'custID' => $cust_data['custID'],
                        'cardNo' => $cust_data['cardNo'],
                        'points' => $points_data['points'],
                        'remark' => $points_data['remark']
                    ];
                    $points_result = WdhService::pointsAdd( $args_points );
                    if ( $points_result['code'] != 200 ) {
                        return response()->json(['code' => 100010, 'message' =>'积分退回失败']);
                    } else {
                        self::trace( $return_no , '积分退回成功',null);
                    }
                }

                //退回余额
                if ( !empty( $balance_data ) ) {

                    $args_balance = [
                        'pcustID' => $cust_data['pcustID'],
                        'custID' => $cust_data['custID'],
                        'cardNo' => $cust_data['cardNo'],
                        'amount' => $balance_data['amount'],
                        'remark' => $balance_data['remark']
                    ];
                    $balance_result = WdhService::recharge( $args_balance );
                    if ( $balance_result['code'] != 200 ) {
                        return response()->json(['code' => 100011, 'message' =>'余额退回失败']);
                    }else {
                        self::trace( $return_no , '余额退回成功',null);
                    }
                }

                //退回微信支付、支付宝等
                if ( !empty( $online_pay_data ) ) {

                    $bill_data = bill::select('split_type','parent_bill_no','bill_payable','billChannel')->find( $online_pay_data['bill_no'] );
                    if ( !$bill_data ) {
                        return response()->json(['code' => 100012, 'message' =>'订单信息不存在']);
                    }

                    $refund_id = 0;

                    $bill_no   = $online_pay_data['bill_no'];
                    if( $bill_data['split_type'] == 3 ){  //订单为子订单
                        $bill_no = $bill_data['parent_bill_no'];
                    }
                    $channelType = '08';//银联渠道类型
                    if ( $bill_data['billChannel'] == 3 ) {
                        $channelType = '07';
                    }

                    $pay_data = BillPay::select('deduct_amount')->where(['bill_no'=>$bill_no,'payTypeID'=>$online_pay_data['payTypeID']])->get()->toArray();
                    if( $online_pay_data['payTypeID'] == 6 ) {  //支付方式为"代付"
                        $online_pay_data['payTypeID'] = 5;
                    }

                    //支付参数
                    $args_data = [
                        'payTypeID' => $online_pay_data['payTypeID'],
                        'transaction_id' => $online_pay_data['pay_code'],
                        'out_trade_no' => $bill_no,
                        'out_refund_no' => $return_no,
                        'total_fee' => $pay_data[0]['deduct_amount'],
                        'refund_fee' => $online_pay_data['deduct_amount'],
                        'refund_reason' => '订单退货',
                        'channelType' => $channelType
                    ];

                    if ( $online_pay_data['payTypeID'] == 4 ) {  //支付宝退款
                        $return_data = WdhService::alipayRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 5 ) {  //微信退款
                        $return_data = WdhService::weixinRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 7 ) {  //百付宝退款
                        $return_data = WdhService::baifubaoRefund( $args_data );
                    } else if ( $online_pay_data['payTypeID'] == 8 ) {  //银联退款
                        $return_data = WdhService::unionpayRefund( $args_data );
                    } else {
                        $return_data = [ 'code' => 100013 , 'message' =>'支付方式有误' ];
                    }

                    if( $return_data['code'] == 200 || $return_data['data']['code'] == 200 ) {

                        if ( isset( $return_data['data']['refund_id']) && !empty( $return_data['data']['refund_id'] ) ) {
                            $refund_id = $return_data['data']['refund_id'];
                        }
                    }

                    self::trace( $return_no , '金额退回中',null);

                    if ( !empty( $refund_id ) ) {
                        BillRefund::where(['refund_no'=>$return_no])->update(['refund_id'=>$refund_id]);
                    }
                }
            }

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100014, 'message' => '退货单快速完成失败']);
        }

        return response()->json(['code' => 200, 'message' =>'ok']);
    }


    /**
     * 订单轨迹
     * @param $bill_no  //订单号
     * @param $bill_status  //订单状态
     * @param $content  //备注
     */
    public function trace( $bill_no ,$bill_status ,$content)
    {

        //保存订单轨迹信息
        $order_trace = new BillTrace;
        $order_trace->uuid = makeUuid();
        $order_trace->timeStamp = Carbon::now();
        $order_trace->creator = 'api';
        $order_trace->createTime = Carbon::now();
        $order_trace->bill_no = $bill_no;
        $order_trace->bill_status = $bill_status;
        $order_trace->content = $content;
        $order_trace->save();

    }


    /**
     * 异步推送订单传入ERP
     * @param $args_array
     */
    public function pushBillToErp( $args_array )
    {

        //保存bill_erp记录
        $bill_erp = new BillErp;
        $bill_erp->uuid = makeUuid();
        $bill_erp->timeStamp = Carbon::now();
        $bill_erp->creator = 'api';
        $bill_erp->createTime = Carbon::now();
        $bill_erp->bill_no = $args_array['bill_no'];
        $bill_erp->bill_status = $args_array['bill_status'];
        $bill_erp->remark = isset($args_array['remark']) ? $args_array['remark'] : '';
        $bill_erp->save();

        $args_data = array(
            'bill_status' => $args_array['bill_status'],
            'bill_no'     => (string)$args_array['bill_no'],
            'remark'      => isset($args_array['remark']) ? $args_array['remark'] : ''
        );

        ApiService::billErp( $args_data );

    }


    /**
     * 保存订单日志
     * @param $args_data
     */
    public function orderLog( $args_data )
    {

        //保存订单轨迹信息
        $log_datail = new LogDetail;
        $log_datail->uuid = makeUuid();
        $log_datail->timeStamp = Carbon::now();
        $log_datail->creator = 'api';
        $log_datail->createTime = Carbon::now();
        $log_datail->logItem = isset( $args_data['logItem'] ) ? $args_data['logItem'] : '';
        $log_datail->logCategoryID = isset( $args_data['logCategoryID'] ) ? $args_data['logCategoryID'] : 0;
        $log_datail->extend_1 = isset( $args_data['extend_1'] ) ? $args_data['extend_1'] : '';
        $log_datail->extend_2 = isset( $args_data['extend_2'] ) ? $args_data['extend_2'] : '';
        $log_datail->extend_3 = isset( $args_data['extend_3'] ) ? $args_data['extend_3'] : '';
        $log_datail->extend_4 = isset( $args_data['extend_4'] ) ? $args_data['extend_4'] : '';
        $log_datail->extend_5 = isset( $args_data['extend_5'] ) ? $args_data['extend_5'] : '';
        $log_datail->extend_6 = isset( $args_data['extend_6'] ) ? $args_data['extend_6'] : '';
        $log_datail->extend_7 = isset( $args_data['extend_7'] ) ? $args_data['extend_7'] : '';
        $log_datail->extend_8 = isset( $args_data['extend_8'] ) ? $args_data['extend_8'] : '';
        $log_datail->extend_9 = isset( $args_data['extend_9'] ) ? $args_data['extend_9'] : '';
        $log_datail->extend_10 = isset( $args_data['extend_10'] ) ? $args_data['extend_10'] : '';
        $log_datail->save();

    }


    /**
     * 订单完成公共方法
     * @return array
     */
    public function commonFinish( $order_no )
    {

        //订单号
        if ( empty( $order_no ) ) {
            return response()->json(['code' => 100000, 'message' => '参数错误']);
        }

        //根据订单号查询订单信息
        $bill_master = Bill::find( $order_no );

        if ( !$bill_master ) {
            return response()->json(['code' => 100001, 'message' => '订单信息不存在']);
        }

        //订单状态:0、建立 1、确认 2、发货 3、配送 4、完成 5、取消 6、异常
        if ( $bill_master['bill_status'] == 0 ) {
            return response()->json(['code' => 100002, 'message' => '订单未审核,请检查订单状态']);
        }
        if ( $bill_master['bill_status'] == 1 && !in_array( $bill_master['bill_status'],array(2, 3, 7) ) ) {
            return response()->json(['code' => 100003, 'message' => '订单未发货,请检查订单状态']);
        }
        if ( $bill_master['bill_status'] == 4 ) {
            return response()->json(['code' => 100004, 'message' => '订单已完成,请检查订单状态']);
        }
        if ( $bill_master['bill_status'] == 5 ) {
            return response()->json(['code' => 100005, 'message' => '订单已取消,请检查订单状态']);
        }

        try {

            //开启事务
            DB::beginTransaction();

            $update['bill_status'] = 4;
            $update['bill_logistics_status'] = 5;

            if ( $bill_master['pay_type'] == 1 ) { //货到付款，更新订单支付状态

                $update['pay_status'] = 1;
                $update['payed_time'] = Carbon::now();
            }

            //更新订单状态为已完成 , 订单物流状态为已完成
            Bill::where(['bill_no'=>$order_no])->update( $update );

            if ( $bill_master['pay_type'] == 1 ) { //货到付款的订单，更新支付状态为人工已审

                $bill_pay = BillPay::where(['bill_no'=>$order_no,'paid_confirm_status'=> 0 ])
                    ->update(['pay_time'=>Carbon::now(),'paid_confirm_status'=>2,'deduct_amount'=>'pay_amount']);
                if ( $bill_pay <= 0 ) {
                    return response()->json(['code' => 100006, 'message' => '订单支付状态更新失败']);
                }
            }

            //更新还未核销的券码状态为已领取（已使用）
            ActivityCodePool::where(['bill_no'=>$order_no,'code_status'=>1 ])
                ->update(['code_status'=>2,'used_time'=>Carbon::now()]);

            //更新订单活动码状态为已领取（未使用）
            BillCodePool::where(['bill_no'=>$order_no,'code_status'=>1])->update(['code_status'=>2]);

            //订单优惠券发放状态更新为已完成
            $bill_coupon = BillCoupon::where( ['bill_no'=>$order_no,'bill_status'=>4 ] );

            //保存订单完成需要发放积分、优惠券等记录
            $bill_finish = new BillFinish;
            $bill_finish->uuid = makeUuid();
            $bill_finish->timeStamp = Carbon::now();
            $bill_finish->creator = 'api';
            $bill_finish->createTime = Carbon::now();
            $bill_finish->bill_no = $order_no;
            $bill_finish->points_grant = $bill_master['bill_totalPoints'] >0 ? 1 :0;
            $bill_finish->inventory_reduction = 0;
            $bill_finish->membership_grade = 0;
            $bill_finish->send_message = 0;
            $bill_finish->coupon_grant = $bill_coupon ? 1 : 0;
            $bill_finish->save();

            BillFinishTemp::where(['bill_no' => $order_no])->delete();

            //生成订单轨迹
            self::trace( $order_no,  4, '您的订单已完成');

            /**
             * 异步推送脚本进行积分、优惠券的发放、库存扣减
             */
            $args_data = [
                'bill_no' => $order_no
            ];
            ApiService::billFinish( $args_data );

            //推送订单创建成功消息模板
            $push_array = [
                'template_scene_id' => '10021',
                'bill_status' => '4',
                'bill_no' => $order_no
            ];
            ApiService::billMessageTemplate( $push_array );

            //异步推送传入ERP处理
            self::pushBillToErp( ['bill_status' => 4, 'bill_no'=> $order_no] );

            DB::commit();

        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json(['code' => 100007, 'message' => '订单完成失败']);
        }

        return response()->json(['code' => 200, 'message' => 'ok']);
    }


    /**
     * 卡券回滚
     * @param $order_no //订单号
     * @return array
     */
    public function rollbackCoupon( $order_no )
    {

        if ( empty( $order_no ) ) {
            return array('code' => 100001, 'message' => '订单号为空');
        }

        $bill_use_card_coupon = BillUseCardCoupon::where(['bill_no' => $order_no])->get()->toArray();

        if ( $bill_use_card_coupon ) {

            foreach ( $bill_use_card_coupon as &$card_coupon) {

                $bill_code = ActivityCodePool::where( ['bill_no'=>$order_no,'barcode'=>$card_coupon['barcode'] ] )->first();
                if ( !$bill_code ) {

                    $coupon = CardCoupon::where(['wncode'=>$card_coupon['barcode']])->get()->toArray();
                    if ( !$coupon ) {
                        return array('code' => 100002, 'message' => '卡券没有找到');
                    }
                    $coupon_id = $coupon[0]['card_id'];
                    $coupon = $coupon[0];

                } else {

                    $coupon_id = $bill_code['card_id'];

                    $coupon = CardCoupon::where(['card_id'=>$coupon_id])->get()->toArray();
                    if ( !$coupon ) {
                        return array('code' => 100003, 'message' => '卡券没有找到');
                    }

                    $coupon = $coupon[0];
                }

                //保存活动码
                $code_pool_obj = new ActivityCodePool;
                $code_pool_obj->uuid = makeUuid();
                $code_pool_obj->timeStamp = Carbon::now();
                $code_pool_obj->creator = 'api';
                $code_pool_obj->createTime = Carbon::now();
                $code_pool_obj->bill_no = $order_no;
                $code_pool_obj->barcode = $card_coupon['barcode'];
                $code_pool_obj->bill_no = null;
                $code_pool_obj->used_time = null;
                $code_pool_obj->code_status = 1;
                $code_pool_obj->save();

                $redis_used_num = Redis::get( 'EBSIG_CARD_COUPON_USED_'.$coupon_id );
                if( empty( $redis_used_num ) ) {
                    Redis::setex('EBSIG_CARD_COUPON_USED_'.$coupon_id,$coupon['useNum']);
                }
                Redis::decr('EBSIG_CARD_COUPON_USED_'.$coupon_id);

                $redis_used_num = Redis::get( 'EBSIG_CARD_COUPON_USED_'.$coupon_id );
                if( $redis_used_num < 0 ){
                    return array('code' => 100004, 'message' => '卡券回滚失败');
                }
            }
        }


        return array('code' => 200, 'message' => 'ok');
    }




}
